/*
 * Copyright (C) 2022 Baidu, Inc. All Rights Reserved.
 */
package com.mobile.centaur.utils;

import android.content.Context;
import android.content.res.AssetManager;
import android.os.StatFs;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Base64;
import android.util.Log;

import androidx.annotation.NonNull;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

public class FileUtil {

    /**
     * 遍历所有文件
     *
     * @param fileAbsolutePath 传入的文件的父目录
     */
    public static Map<String, String> getFileName(final String fileAbsolutePath) {
        Map<String, String> map = new HashMap<>();
        File file = new File(fileAbsolutePath);
        File[] subFile = file.listFiles();
        try {
            if (subFile.length > 0) {
                for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
                    // 判断是否为文件夹
                    if (!subFile[iFileLength].isDirectory()) {
                        String filename = subFile[iFileLength].getName();
                        map.put(String.valueOf(iFileLength), filename);
                    }
                }
            }
        } catch (NullPointerException e) {
            e.toString();
        }
        return map;
    }

    public static boolean createOrExistsFile(File mFile) {
        if (mFile.exists())
            mFile.delete();
        if (!mFile.exists()) {
            try {
                return mFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return false;
        }
    }

    public static boolean createOrExistsDir(String path) {
        return createFileDir(new File(path));
    }

    /**
     * 创建文件夹---之所以要一层层创建，是因为一次性创建多层文件夹可能会失败！
     */
    public static boolean createFileDir(File dirFile) {
        if (dirFile == null) return true;
        if (dirFile.exists()) {
            return true;
        }
        File parentFile = dirFile.getParentFile();
        if (parentFile != null && !parentFile.exists()) {
            //父文件夹不存在，则先创建父文件夹，再创建自身文件夹
            return createFileDir(parentFile) && createFileDir(dirFile);
        } else {
            boolean mkdirs = dirFile.mkdirs();
            boolean isSuccess = mkdirs || dirFile.exists();
            if (!isSuccess) {
                Log.e("FileUtil", "createFileDir fail " + dirFile);
            }
            return isSuccess;
        }
    }

    /**
     * 读取日志文件
     *
     * @param file 本地txt或log文件
     * @return 返回读取到的文件内容
     */
    public static String getFileContent(File file) {
        String content = null;
        try {
            InputStream is = new FileInputStream(file);
            InputStreamReader reader = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                content = content + line + "\n";
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.toString();
        }
        return content;
    }

    /**
     * 删除文件，可以是文件或文件夹
     *
     * @param fileName 要删除的文件名
     * @return 删除成功返回true，否则返回false
     */
    public static boolean delete(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            System.out.println("删除文件失败:" + fileName + "不存在！");
            return false;
        } else {
            if (file.isFile())
                return deleteFile(fileName);
            else
                return deleteDirectory(fileName);
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName 要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName.replaceAll(" ", ""));
        //Log.w("file", "fileName:" + fileName);
        //Log.w("TAG", "file.isFile():" + file.isFile());
        if (file.isFile() || file.exists()) {
            boolean isDel = file.delete();
            Log.w("file", "删除文件:" + fileName);
            return isDel;
        } else {
            Log.e("MainActivity", "删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }

    /**
     * 删除目录及目录下的文件
     *
     * @param dir 要删除的目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        File dirFile = new File(dir);
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            System.out.println("删除目录失败：" + dir + "不存在！");
            return false;
        }
        boolean flag = true;
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            } else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i]
                        .getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag) {
            System.out.println("删除目录失败！");
            return false;
        }
        if (dirFile.delete()) {
            System.out.println("删除目录" + dir + "成功！");
            return true;
        } else {
            return false;
        }
    }

    /**
     * 将图片转换成Base64编码的字符串
     */
    public static String imageToBase64(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        InputStream is = null;
        byte[] data = null;
        String result = null;
        try {
            is = new FileInputStream(path);
            //创建一个字符流大小的数组。
            data = new byte[is.available()];
            //写入数组
            is.read(data);
            //用默认的编码格式进行编码
            result = Base64.encodeToString(data, Base64.NO_CLOSE);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return result;
    }

    /**
     * 将Base64编码转换为图片
     *
     * @param base64Str
     * @param path
     * @return true
     */
    public static boolean base64ToFile(String base64Str, String path) {
        byte[] data = Base64.decode(base64Str, Base64.NO_WRAP);
        for (int i = 0; i < data.length; i++) {
            if (data[i] < 0) {
                //调整异常数据
                data[i] += 256;
            }
        }
        OutputStream os = null;
        try {
            os = new FileOutputStream(path);
            os.write(data);
            os.flush();
            os.close();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    //获取SD卡可用空间
    public static String getSDAvailableSize(Context context) {
//        File[] dirs = context.getExternalFilesDirs(null);
        try {
            StatFs stat = new StatFs(Common.getInstance().getPATH_SAVE_VIDEO());
            long blockSize = stat.getBlockSizeLong();
            long availableBlocks = stat.getAvailableBlocksLong();
//            long totalBlocks = stat.getBlockCount();
            //String s1 = Formatter.formatFileSize(context, blockSize * totalBlocks);
            String s2 = Formatter.formatShortFileSize(context, blockSize * availableBlocks);
            return s2;
        } catch (Exception e) {
            e.printStackTrace();
            return "ERROR";
        }
    }

    /**
     * @return 路径信息
     */
    public static StorageInfo getStorageInfo(Context context, String path) {
        StorageInfo storageInfo = new StorageInfo();
        try {
            StatFs stat = new StatFs(Common.getInstance().getPATH_SAVE_VIDEO());
            long blockSize = stat.getBlockSizeLong();
            long availableBlocks = stat.getAvailableBlocksLong();
            long totalBlocks = stat.getBlockCountLong();
            storageInfo.availableSize = availableBlocks * blockSize;
            storageInfo.totalSize = totalBlocks * blockSize;
            storageInfo.shortFileSize = Formatter.formatShortFileSize(context, storageInfo.availableSize);
            storageInfo.availablePercent = (int) ((double) availableBlocks / (double) totalBlocks * 100);
            storageInfo.alreadyUsedPercent = 100 - storageInfo.availablePercent;
            return storageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            return storageInfo;
        }
    }

    public static class StorageInfo {
        /**
         * 短文件大小，类似 8GB
         */
        public String shortFileSize = "";
        /**
         * 空闲大小
         */
        public long availableSize = 0;

        /**
         * 总大小
         */
        public long totalSize = 0;

        /**
         * 空闲百分比
         */
        public int availablePercent = 0;

        /**
         * 已用百分百
         */
        public int alreadyUsedPercent = 0;

        @NonNull
        public String toString() {
            return "总大小：" + shortFileSize + ",空闲大小:" + availableSize + "，空闲百分比：" + availablePercent + "，已用百分比：" + alreadyUsedPercent;
        }
    }

    public static long getTotalBlocks() {
        try {
            StatFs stat = new StatFs(Common.getInstance().getPATH_SAVE_VIDEO());
            long blockSize = stat.getBlockSizeLong();
            return stat.getBlockCount() * blockSize;
        } catch (Exception e) {
            return 0;
        }

    }

    /**
     * 内存不够时清除部分数据
     *
     * @param minSize 最小空间，低于此大小将删除一个文件夹
     */
    public static void clearData(String path, long minSize) {
        StatFs stat = new StatFs(path);
        long blockSize = stat.getBlockSizeLong();
        long availableBlocks = stat.getAvailableBlocksLong();
        long l = blockSize * availableBlocks;
        Log.i("file", "剩余空间：" + l + "byte");
        if (l < minSize) {
            Log.i("file", "存储空间不足，将删掉部分文件");
            File file = new File(path);
            File[] files = file.listFiles();
            if (files != null && files.length != 0) {
                File tempFile = null;
                for (File f : files) {
                    if (tempFile == null && f.getName().startsWith("20") && f.isDirectory()) {
                        tempFile = f;
                        continue;
                    }
                    if (f.getName().startsWith("20") && f.isDirectory() && f.lastModified() < tempFile.lastModified()) {
                        tempFile = f;
                        //Log.i("file", "赋值:" + tempFile.getAbsolutePath());
                    } else {
                        Log.i("file", "跳过:" + f.getAbsolutePath());
                    }
                }
                if (tempFile.getName().startsWith("20") && tempFile.isDirectory()) {
                    Log.i("file", "删除:" + tempFile.getAbsolutePath());
                    deleteDirectory(tempFile.getAbsolutePath());
                } else {
                    Log.i("file", "删除失败:" + tempFile.getAbsolutePath());
                }
            } else {
                Log.i("file", "空文件夹：" + path);
            }

        }
    }

    public static String readStringFromAssets(Context context, String fileName) {
        //通过设备管理对象 获取Asset的资源路径
        AssetManager assetManager = context.getApplicationContext().getAssets();

        InputStream inputStream = null;
        InputStreamReader isr = null;
        BufferedReader br = null;

        StringBuffer sb = new StringBuffer();
        try {
            inputStream = assetManager.open(fileName);
            isr = new InputStreamReader(inputStream);
            br = new BufferedReader(isr);

            sb.append(br.readLine());
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append("\n").append(line);
            }

            br.close();
            isr.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }


}